﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;

namespace MessageWorkflow
{
    public sealed class ReaderWriterLockSlim : IDisposable
    {    
        private readonly object _internalLock = new object();    
        private int _activeReaders = 0;    
        private Thread _activeWriterThread;    
        
        public void EnterReadLock()    
        {        
            lock (_internalLock)        
            {
                while (_activeWriterThread != null)                
                    Monitor.Wait(_internalLock);           
                ++_activeReaders;        
            }    
        }    
        public void ExitReadLock()    
        {        
            lock (_internalLock)        
            {            
                // if _activeReaders <= 0 do some error handling            
                --_activeReaders;            
                Monitor.PulseAll(_internalLock);        
            }    
        }    
        
        public void EnterWriteLock()    
        {        
            lock (_internalLock)        
            {            
                // first wait for any writers to clear             
                // This assumes writers have a higher priority than readers            
                // as it will force the readers to wait until all writers are done.            
                // you can change the conditionals in here to change that behavior.            
                while (_activeWriterThread != null && _activeWriterThread != Thread.CurrentThread)                
                    Monitor.Wait(_internalLock);            
                
                // There are no more writers, set this to true to block further readers from acquiring the lock            
                _activeWriterThread = Thread.CurrentThread;            
                // Now wait till all readers have completed.            
                while (_activeReaders > 0)                
                    Monitor.Wait(_internalLock);            
                // The writer now has the lock        
            }    
        }    

        public void ExitWriteLock()    
        {        
            lock (_internalLock)        
            {            
                // if activeWriter != true handle the error           
                _activeWriterThread = null;            
                Monitor.PulseAll(_internalLock);        
            }    
        }

        public void EnterUpgradeableReadLock()
        {
            EnterReadLock();
        }

        public void ExitUpgradeableReadLock()
        {
            ExitReadLock();
        }

        public void Dispose()
        {
            
        }
    }
}
